package com.channel.temperature.collect.app.util

import java.io.ByteArrayOutputStream
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.PublicKey
import java.security.interfaces.RSAPrivateKey
import java.security.spec.PKCS8EncodedKeySpec
import java.util.Base64
import javax.crypto.Cipher


object RSAUtils {
    val transformation = "RSA"

    //注意自己生成的密钥对的bits长度
    val ENCRYPT_MAX_SIZE = 245//加密每次最大加密字节
    val DECRYPT_MAX_SIZE = 256//解密每次最大加密字节

    //我的私钥
    val privateKeyString = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDWP0GJ1WoWuIGR" +
            "X+54U2Yitsf2SEQqeI5QEbi55YZ287CskGpmDHeSQcEU3SS3Mrk4KzGVmUczqEIG" +
            "j/X/aAWh1Vcvueuu3Las4EOBx3Djo8FQNMVSUVFWXmzd1bv1v+YW/gFWqRpc8ibD" +
            "bozIg0U3UxVVwGGMDG7qF1rXREFOEl7Egi47uIAzejeBcYA+sthFJfKT6jgz15Bn" +
            "E+pQ2hbbEXzo2OCxZPppiQ/Lyq20whDXIotmefiqkKEUhS0m4zB5L/dRx+dDU+Pn" +
            "0BEusOHTNUQKkxNM6kv7P4ozzHVaYN8BOTTWWW+MSx4TBN8IKrAhUa4q79XVmVeV" +
            "abH0t8NNAgMBAAECggEBAI1SwIqJCifeoSkh3I3mhXLUmuZsGPri9wz+A5osOxxv" +
            "9tR9lpGmG6GQWirHDRcDEIZqh5SkvQDoNlVZ1O0a0sxDi/VhcIOx95XlgOI0itS+" +
            "CiA8DwUTutF8C9fwysF6Se5UstFVTpyM5uD3JUqGvLuXxHUCJ9ZXxToJGdTxoxo5" +
            "crJlXIrV025ySI2EtKgzWcU3aARgj/D+rq4upczuhW4miNc+cUuXdVaz0TlDKi8i" +
            "bOWCtXYbFSAW3v1nID+VVoKpsJrGrF2KdGoYzLHodm50TuRS6/5bkrtkdlcCLCNE" +
            "DHijQwDBIgndmSj5hNNA1fuwnu8euZIRbAefEG9htcECgYEA83dzMEPwk9JgLMVb" +
            "78jBX6+rlA7xH9BwDvl9i1RywG3ZewIs647SvbpeC6mmUxMPCb04KpQ+wVZLqPOJ" +
            "Q1NYxsJwY9tNOOzDfcd4cfnZHvY76jB+i51+oGaNK2SokrfdLYq6a9Bpv/URnBlp" +
            "ayqszfF4E2lJ4phQSj9FQwuSFKUCgYEA4Ua71RgoxGG7Kybh8uA6WFSRZdQGm2Gl" +
            "1COLhbqcQ77JOmV/XPTBcLNUhENfeAaXcZl5RxSHWf0QlyC/GTJW6pKQm8k/K/9s" +
            "9otUldJzcZMvENIBAoUO+b45rGxurs94w1rCUdo+jERhcDfRWqhKy26kL6HiukFI" +
            "Wk1S/X5XK4kCgYEA02U8FwRmt3NLHpSepyzg+nxFtmDi7ITHR7lJUNkaagr3ct8I" +
            "sd9pDGPtlKLRUACUZhht1Eqz0ptjRmdvH44W3z2k6I9aFbs+Ys/3vL77zu5uR4Gj" +
            "3wX5FLz2hl74H6yV1x1FkKd9qrbXe3p1FiAPuyGW6QPaq20lCdK2COjbBiECgYBf" +
            "47PgKMBxlwgMfih/MWKkZprdNTr6uL3VZqvk6GHLlFIjQUDNWIFeb3byNZtVg7jC" +
            "6gjtcJeMfmOpcI7nMr48ataS+T6ig77l0rjWbRYmqffGuR0k7W5Kb+YstpsGXdmR" +
            "jfhYzwUAv7qaAahjZm8v2JCaldXkYhViGrfQnw6LwQKBgQC7UkzGXAUbJ4VCAfDT" +
            "MSYiTxALBP1Ug6cjm9Uib2mscLQE9t2lEZ6z8C8wTkRtHZSIZqoxPMrbyo1aQWPi" +
            "ZejJcrKR73fD+4dE1/vGtZTjfPO9Ca6pEtzv66s//GWqJruVq9uCSqam5OKtf3a9" +
            "6oYjNDMMQ7OC8NJlyk1Ym/SSPA=="

    //php的公钥
    val publicKeyString = "MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQB+tC9Bf24C4zXPhbnX6MXl" +
            "37FNH5clkylehBU3oP9hn9+UWzCLVTUGMXxEBsOBYg6nbS1DB21CSzjw0YPmhsrl" +
            "luprc4K9PIjk98D+2wgjVq8ggZSACqm//BVLjGA93+kd6KHu72pM5MCccdFgqgP7" +
            "oda/9UYj3QcwHV1lIpP12OFZtYsFDV6kk5mZMID0F7zTTzsdCHB6hWfyoveGbjpQ" +
            "gSMyJmNGv8eNpFuf9PRTCXxrKFlAf0rwrSr8L61n89DWmRfHKVang7ET5VEiuqc9" +
            "XFtqg/bkiEuyMFoxvOq1HA7Sbbj28TdevphSYs707/007Dv0pzsgZFm/DPLx96GR" +
            "AgMBAAE="

    /**
     * 公钥加密
     * @param input 原文
     * @param publicKey 公钥
     */
    fun encryptByPublicKey(input: String, publicKey: PublicKey): String {

        //****非对称加密****
        //创建cipher对象
        val cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        //加密
        val encrypt = cipher.doFinal(input.toByteArray())

        return String(Base64.getEncoder().encode(encrypt))

    }

    public fun decrypt(str: String, privateKey: String): String {
        //64位解码加密后的字符串
        var inputByte = Base64.getDecoder().decode((str.toByteArray()))
        //base64编码的私钥
        var decoded = Base64.getDecoder().decode(privateKey)

        var priKey = KeyFactory.getInstance("RSA")
            .generatePrivate(PKCS8EncodedKeySpec(decoded)) as RSAPrivateKey
        //RSA解密
        var cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
        cipher.init(Cipher.DECRYPT_MODE, priKey)
        var outStr = String(cipher.doFinal(inputByte));
        return outStr;
    }

    /**
     * 私钥分段加密
     * @param input 原文
     * @param privateKey 私钥
     */
    fun segmentEncryptByPrivateKey(input: String, privateKey: PrivateKey): String {

        //创建cipher对象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, privateKey)

        //****非对称加密****
        val byteArray = input.toByteArray()

        //分段加密
        var temp: ByteArray? = null
        var offset = 0 //当前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0) {
            //每次最大加密245个字节
            if (byteArray.size - offset >= ENCRYPT_MAX_SIZE) {
                //剩余部分大于245
                //加密完整245
                temp = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
                //重新计算偏移位置
                offset += ENCRYPT_MAX_SIZE
            } else {
                //加密最后一块
                temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                //重新计算偏移位置
                offset = byteArray.size
            }
            //存储到临时的缓冲区
            outputStream.write(temp)
        }
        outputStream.close()

        return String(Base64.getEncoder().encode(outputStream.toByteArray()))

    }

    /**
     * 公钥分段加密
     * @param input 原文
     * @param publicKey 公钥
     */
    fun segmentEncryptByPublicKey(input: String, publicKey: PublicKey): String {

        //创建cipher对象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        //加密
//        val encrypt = cipher.doFinal(input.toByteArray())

        //****非对称加密****
        val byteArray = input.toByteArray()

        var temp: ByteArray? = null
        var offset = 0 //当前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0) {
            //每次最大加密117个字节
            if (byteArray.size - offset >= ENCRYPT_MAX_SIZE) {
                //剩余部分大于117
                //加密完整117
                temp = cipher.doFinal(byteArray, offset, ENCRYPT_MAX_SIZE)
                //重新计算偏移位置
                offset += ENCRYPT_MAX_SIZE
            } else {
                //加密最后一块
                temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                //重新计算偏移位置
                offset = byteArray.size
            }
            //存储到临时的缓冲区
            outputStream.write(temp)
        }
        outputStream.close()

        return String(Base64.getEncoder().encode(outputStream.toByteArray()))

    }

    /**
     * 私钥分段解密
     * @param input 秘文
     * @param privateKey 私钥
     */
    fun segmentDecryptByPrivateKey(input: String, privateKey: PrivateKey): String {

        //创建cipher对象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.DECRYPT_MODE, privateKey)

        //****非对称加密****
        val byteArray = Base64.getDecoder().decode(input)

        //分段解密
        var temp: ByteArray? = null
        var offset = 0 //当前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0) {
            //每次最大解密256个字节
            if (byteArray.size - offset >= DECRYPT_MAX_SIZE) {

                temp = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
                //重新计算偏移位置
                offset += DECRYPT_MAX_SIZE
            } else {
                //加密最后一块
                temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                //重新计算偏移位置
                offset = byteArray.size
            }
            //存储到临时的缓冲区
            outputStream.write(temp)
        }
        outputStream.close()

        return String(outputStream.toByteArray())

    }

    /**
     * 公钥分段解密
     * @param input 秘文
     * @param privateKey 公钥
     */
    fun segmentDecryptByPublicKey(input: String, publicKey: PublicKey): String {

        //创建cipher对象
        val cipher = Cipher.getInstance(transformation)
        //初始化cipher
        cipher.init(Cipher.DECRYPT_MODE, publicKey)

        //****非对称加密****
        val byteArray = Base64.getDecoder().decode(input)

        //分段解密
        var temp: ByteArray? = null
        var offset = 0 //当前偏移的位置

        val outputStream = ByteArrayOutputStream()

        //拆分input
        while (byteArray.size - offset > 0) {
            //每次最大解密256个字节
            if (byteArray.size - offset >= DECRYPT_MAX_SIZE) {

                temp = cipher.doFinal(byteArray, offset, DECRYPT_MAX_SIZE)
                //重新计算偏移位置
                offset += DECRYPT_MAX_SIZE
            } else {
                //加密最后一块
                temp = cipher.doFinal(byteArray, offset, byteArray.size - offset)
                //重新计算偏移位置
                offset = byteArray.size
            }
            //存储到临时的缓冲区
            outputStream.write(temp)
        }
        outputStream.close()

        return String(outputStream.toByteArray())

    }

}